package com.ruoyi.quartz.task;

import com.google.common.util.concurrent.*;
import com.ruoyi.bizsys.domain.RepaymentOrder;
import com.ruoyi.bizsys.service.IExtMonnifyReservedAccountsService;
import com.ruoyi.bizsys.service.IRepaymentOrderService;
import com.ruoyi.business.service.IBRepaymentService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.quartz.thread.TransferToUsThread;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component("transferToUsTask")
public class TransferToUsTask {

    @Autowired
    RedisCache redisCache;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    IRepaymentOrderService iRepaymentOrderService;

    @Autowired
    IBRepaymentService iBRepaymentService;

    @Autowired
    IExtMonnifyReservedAccountsService extMonnifyReservedAccountsService;
    @Autowired
    IRepaymentOrderService repaymentOrderService;

    public void killTransferToUsThread(){
        log.info("执行杀死全部TransferToUs线程");
        redisTemplate.delete(redisTemplate.keys(BizConstants.TRANSFER_TO_US_THREAD+"*"));
        //判断当前时间是大于23点小于23:05 update set repayStatus = 10 repaymentOrder where repayStatus in 2,5 and createTime<23点
        if(checkIsBetweenTodayHHss(new Date(),"23:00","23:05")){
            log.info("23的paystask定时任务设置repaymentOrder失效");
            // 防止索引失效：DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD+" 23:00")
            repaymentOrderService.updateRepayStatusToFaild(DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD+" 23:00"));
        }
    }

    //@PostConstruct
    public void runTransferToUsThread(){

//        RepaymentOrder repaymentOrder = new RepaymentOrder();
//        repaymentOrder.setRepayStatus(2);
//        repaymentOrder.setActionType(BizConstants.LOAN_REPAYMENT_ORDER_TYPE_TTS);
//        repaymentOrder.setState("1");
        List<RepaymentOrder> list = iBRepaymentService.getToActionTypeAndLoanSerialNo(BizConstants.LOAN_REPAYMENT_ORDER_TYPE_TTS,"");
        int count = list.size();
        if (count > 0) {
            String redisName = BizConstants.TRANSFER_TO_US_TASK_DATA;

            int threadStep = 10;//每个线程执行的客户数
            //需要multiple个线程来执行
            int threadCount = count / threadStep;
            if (threadCount * threadStep != count) {
                threadCount++;
            }
            //线程计数器
            final CountDownLatch countDownLatch = new CountDownLatch(threadCount);
            //线程池大小
            int poolSize = 2;

            ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
            ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);

            int threadAccountCount = 0;
            while (threadAccountCount != count) {
                //分页取数startNum
                int startLimit = threadAccountCount;

                threadAccountCount += threadStep;

                if(threadAccountCount>count){
                    threadAccountCount = count;
                }

                String redisName1 = redisName+":"+startLimit+"-"+threadAccountCount;
                List<RepaymentOrder> accountList1 = list.subList(startLimit,threadAccountCount);
                redisCache.setCacheList(redisName1,accountList1);
                redisCache.expire(redisName1,23, TimeUnit.HOURS);

                TransferToUsThread thread = new TransferToUsThread("[ransferToUsTask-"+startLimit+"]", redisName1,
                        iBRepaymentService,redisCache,iRepaymentOrderService,extMonnifyReservedAccountsService);
                ListenableFuture listenableFuture = listeningExecutorService.submit(thread);

                Futures.addCallback(listenableFuture, new FutureCallback<String>() {
                    @Override
                    public void onSuccess(String result) {
                        countDownLatch.countDown();
                        log.info("["+this.getClass().getName()+"]线程处理结果："+ result);
                    }

                    @Override
                    public void onFailure(Throwable throwable) {
                        countDownLatch.countDown();
                        log.info("["+this.getClass().getName()+"]线程处理出错："+ throwable);
                    }
                });
            }

            try {
                countDownLatch.await(3*60, TimeUnit.MINUTES);//超过3个小时放弃
            } catch (InterruptedException e) {
                log.error("ransferToUsTask当日跑批执行失败，非正常结束", e);
            }
        }else {
            log.info("ransferToUsTask每日跑批任务没有记录需要执行");
        }

        log.info("ransferToUsTask每日跑批任务 End>>>>>>>>>>");
    }


    /**
     *    aTime(23：00)  <= 当前时间 < bTime(23:10);
     * @param bTime
     * @param aTime
     * @param cTime
     * @return
     */
    private static Boolean checkIsBetweenTodayHHss(Date bTime, String aTime, String cTime){
        long leftTime = DateUtils.parseDate(DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD+" "+aTime)).getTime();
        long rightTime = DateUtils.parseDate(DateFormatUtils.format(new Date(), DateUtils.YYYY_MM_DD+" "+cTime)).getTime();
        if(leftTime <= bTime.getTime() && bTime.getTime() < rightTime){
            return true;
        }
        return false;
    }
}
